﻿<!DOCTYPE HTML>
<html lang="zh">
<head>
<title>遍历文件 - 语法 &amp; 使用 | AutoHotkey v2</title>
<meta name="description" content="The 遍历文件 statement retrieves the specified files or folders, one at a time." />
<meta name="ahk:equiv-v1" content="commands/LoopFile.htm" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<link href="../static/theme.css" rel="stylesheet" type="text/css" />
<script src="../static/content.js" type="text/javascript"></script>
<script type="text/javascript">$(function(){0<=window.navigator.userAgent.toLowerCase().indexOf("ucbrowser")&&CaoNiMaDeUc()})</script>
</head>
<body>

<h1>遍历文件</h1>
<p>检索指定的文件或文件夹, 每次一个.</p>

<pre class="Syntax"><span class="func">遍历文件</span> FilePattern <span class="optional">, Mode</span></pre>

<h2 id="Parameters">参数</h2>
<dl>

  <dt>FilePattern</dt>
  <dd>
      <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
      <p>单个文件或文件夹的名称, 或者通配符模式, 如 "C:\Temp\*.tmp". 如果未指定绝对路径, 则假定 <em>FilePattern</em> 在 <a href="../Variables.htm#WorkingDir">内_工作目录</a> 中.</p>
      <p>支持星号和问号作为通配符使用. 当模式出现在文件的长/普通名称或其 <a href="#LoopFileShortName">8.3  短名称</a>时出现匹配.</p>
      <p>如果此参数为单个文件或文件夹(即不含通配符) 且 <em>Mode</em> 包含 <code>R</code>, 同时指定的文件名出现在多个被搜索的文件夹中, 那么将找到多个匹配.</p>
  </dd>

  <dt>Mode</dt>
  <dd>
      <p>类型: <a href="../Concepts.htm#strings">字符串</a></p>
      <p>可选的字符串, 零个或多个下列字母:</p>
      <p><code>D</code>: 包含目录(文件夹).<br>
      <code>F</code>: 包含文件. 如果同时省略 F 和 D, 则仅包含文件而不包括目录.<br>
      <code>R</code>: 递归到子目录(子文件夹). 所有子文件夹都将被递归到其中, 而不仅仅是那些名称匹配 <em>FilePattern</em> 的子文件夹. 如果省略 R, 则不包含子目录中的文件和目录.</p>
  </dd>
  
</dl>

<h2 id="Special_Variables_Available_Inside_a_File-Loop">可在文件循环中使用的特殊变量</h2>
<p>下列变量存在于任何文件循环中. 如果一个内层文件循环包含在一个外层文件循环中, 那么最内层循环的文件将具有优先权:</p>
<table class="info">
  <tr id="LoopFileName">
    <td>内_遍历文件名</td>
    <td>当前检索的文件或文件夹的名称(不包括路径).</td>
  </tr>
  <tr id="LoopFileExt">
    <td>内_遍历文件扩展名</td>
    <td>文件的扩展名(例如 TXT, DOC 或 EXE). 不包括点号(.).</td>
  </tr>
  <tr id="LoopFilePath">
    <td>内_遍历文件路径</td>
    <td>当前检索的文件/文件夹的路径和名称. 如果 <em>FilePattern</em> 包含相对路径而不是绝对路径, 这里的路径也将是相对路径. 此外, <em>FilePattern</em> 中的任何短(8.3) 文件夹名称仍将为短名称(参阅下一项目以获得长文件名).</td>
  </tr>
  <tr id="LoopFileFullPath">
    <td>内_遍历文件全路径</td>
    <td>这与 内_遍历文件路径 有以下不同: 1) 它总是包含文件的绝对/完整路径, 即使 <em>FilePattern</em> 包含相对路径; 2) <em>FilePattern</em> 本身的任何短(8.3) 文件夹名都会被转换为长文件名; 3) <em>FilePattern</em> 中的字符会被转换为大写或小写以匹配文件系统中存储的大小写. 这对于将文件名 -- 例如作为命令行参数传入脚本的文件名 -- 转换为资源管理器显示的准确路径名很有用.</td>
  </tr>
  <tr id="LoopFileShortPath">
    <td>内_遍历文件短路径</td>
    <td><p>当前检索文件/文件夹的 8.3 短路径和名称. 例如: C:\MYDOCU~1\ADDRES~1.txt. 如果 <em>FilePattern</em> 包含相对路径而不是绝对路径, 这里的路径也将是相对路径.</p>
      <p>要检索单个文件或文件夹的完整的 8.3 路径和名称, 像这个例子那样在 <em>FilePattern</em> 中指定其名称:</p>
<pre>遍历文件, "C:\My Documents\Address List.txt"
    ShortPathName := 内_遍历文件短路径</pre>
        <p class="note"><strong>注意</strong>: 如果文件没有短文件名, 这个变量将为<strong>空</strong>, 这可能发生在注册表中设置了 NtfsDisable8dot3NameCreation 的系统中. 如果 <em>FilePattern</em> 包含一个相对路径并且循环的主体使用 <a href="SetWorkingDir.htm">设置工作目录</a> 从循环本身的工作目录中切换出来, 那么这个变量也将是空白的.</p></td>
  </tr>
  <tr id="LoopFileShortName">
    <td>内_遍历文件短名</td>
    <td>文件的 8.3 短名称, 或备用名称. 如果文件没有短文件名(由于长文件比 8.3 短, 或者可能因为 NTFS 文件系统禁用了短文件名的生成), 将检索 <em>内_遍历文件名</em>.</td>
  </tr>
  <tr id="LoopFileDir">
    <td>内_遍历文件目录</td>
    <td><em>内_遍历文件名</em> 所在目录的路径. 如果 <em>FilePattern</em> 包含相对路径而不是绝对路径, 那么这里的路径也将是相对路径. 根目录不会包含反斜杠. 例如: C:</td>
  </tr>
  <tr id="LoopFileTimeModified">
    <td>内_遍历文件修改时间</td>
    <td>文件最后修改的时间. 格式为 <a href="FileSetTime.htm">YYYYMMDDHH24MISS</a>.</td>
  </tr>
  <tr id="LoopFileTimeCreated">
    <td>内_遍历文件创建时间</td>
    <td>文件创建的时间. 格式为 <a href="FileSetTime.htm">YYYYMMDDHH24MISS</a>.</td>
  </tr>
  <tr id="LoopFileTimeAccessed">
    <td>内_遍历文件访问时间</td>
    <td>文件最后访问的时间. 格式为 <a href="FileSetTime.htm">YYYYMMDDHH24MISS</a>.</td>
  </tr>
  <tr id="LoopFileAttrib">
    <td>内_遍历文件属性</td>
    <td>当前检索文件的<a href="FileGetAttrib.htm">属性</a>.</td>
  </tr>
  <tr id="LoopFileSize">
    <td>内_遍历文件大小</td>
    <td>当前检索文件的大小, 以字节为单位. 支持大于 4 GB 的文件.</td>
  </tr>
  <tr id="LoopFileSizeKB">
    <td>内_遍历文件大小KB</td>
    <td>当前检索文件的大小, 以 KB 为单位, 向下取整到最近的整数.</td>
  </tr>
  <tr id="LoopFileSizeMB">
    <td>内_遍历文件大小MB</td>
    <td>当前检索文件的大小, 以 Mb 为单位, 向下取整到最近的整数.</td>
  </tr>
</table>

<h2 id="Remarks">备注</h2>
<p>当你想对一系列文件和/或文件夹进行操作时, 文件循环非常有用, 每次一个.</p>
<p>所有匹配的文件都会被检索出来, 包括隐藏的文件. 相比之下, 操作系统的功能, 如 DIR 命令, 默认情况下会省略隐藏文件. 为了避免处理隐藏的, 系统的, 和/或只读的文件, 在循环中使用类似下面的方法:</p>
<pre>如果 内_遍历文件属性 ~= "[HRS]"  <em>; 跳过任何具有 H(隐藏), R(只读) 或 S(系统). 请参阅 <a href="../Variables.htm#regex">~= 运算符</a>.</em>
    跳过  <em>; 跳过这个文件并继续下一个文件.</em></pre>
<p>在递归搜索过程中, 要检索文件的相对路径而不是绝对路径, 在循环之前使用 <a href="SetWorkingDir.htm">设置工作目录</a> 改变基文件夹, 然后在循环中省略路径(例如 <code>遍历文件, "*.*", "R"</code>). 这将导致 <a href="#LoopFilePath">内_遍历文件路径</a> 包含相对于基文件夹的文件路径.</p>
<p>如果一个文件循环在它自己的权限范围内创建或重命名文件或文件夹, 它可能会自乱阵脚. 例如, 如果通过 <a href="FileMove.htm">文件移动</a> 或其他方式重命名文件, 每个这样的文件可能会被发现两次: 一次是旧名, 另一次是新名. 为了解决这个问题, 只有在创建文件列表后才重命名这些文件. 例如:</p>
<pre>FileList := &quot;&quot;
遍历文件, "*.jpg"
    FileList .= 内_遍历文件名 &quot;`n&quot;
循环转换, FileList, "`n"
    文件移动 内_循环属性, "renamed_" 内_循环属性</pre>
<p>在 NTFS 文件系统中的文件可能总是按字母顺序来获取. 在其他文件系统中的文件则没有特殊的获取顺序. 要使用特殊的获取顺序, 使用 <a href="Sort.htm">排序</a> 命令, 如同下文示例部分演示的那样.</p>
<p>文件和文件夹的完整路径名称超过 259 个字符时, 这些文件和文件夹会被跳过, 就像它们不存在一样. 这样的文件很罕见, 因为操作系统一般不允许创建它们.</p>
<p>请参阅 <a href="Loop.htm">循环</a> 了解关于<a href="Block.htm">区块</a>, <a href="Break.htm">跳出</a>, <a href="Continue.htm">跳过</a> 和 内_循环次数 变量(其存在于各种类型的循环中) 的相关信息.</p>

<h2 id="Related">相关</h2>
<p><a href="Loop.htm">循环</a>, <a href="Break.htm">跳出</a>, <a href="Continue.htm">跳过</a>, <a href="Block.htm">区块</a>, <a href="SplitPath.htm">分割路径</a>, <a href="FileSetAttrib.htm">文件设置属性</a>, <a href="FileSetTime.htm">文件设置时间</a></p>

<h2 id="Examples">示例</h2>
<div class="ex" id="ExBasic">
<p><a href="#ExBasic">#1</a></p>
<pre>遍历文件, 内_程序文件 "\*.txt", "R"  <em>; 递归子文件夹.</em>
{
    Result := 信息框("Filename = " 内_遍历文件路径 "`n`nContinue?",, "y/n")
    如果 Result = "No"
        跳出
}</pre>
</div>

<div class="ex" id="ExSize">
<p><a href="#ExSize">#2</a>: 计算文件夹的大小, 包括其所有子文件夹中的文件:</p>
<pre>FolderSizeKB := 0
WhichFolder := 目录选择框()  <em>; 让用户选取文件夹.</em>
遍历文件, WhichFolder "\*.*", "R"
    FolderSizeKB += 内_遍历文件大小KB
信息框 "Size of " WhichFolder " is " FolderSizeKB " KB."</pre>
</div>

<div class="ex" id="ExSortName">
<p><a href="#ExSortName">#3</a>: 获取根据名称排序的文件名(要以日期排序请参阅下一个例子):</p>
<pre>FileList := &quot;&quot;  <em>; Initialize to be blank.</em>
遍历文件, "C:\*.*"
    FileList .= 内_遍历文件名 &quot;`n&quot;
FileList := 排序(FileList, "R")  <em>; R 选项逆序排列. 有关其他选项, 请参阅 <a href="Sort.htm">排序</a>.</em>
循环转换, FileList, "`n"
{
    如果 内_循环属性 = &quot;&quot;  <em>; 忽略列表末尾的空项.</em>
        跳过
    Result := 信息框("File number " 内_循环次数 " is " 内_循环属性 ".  跳过?",, "y/n")
    如果 Result = "No"
        跳出
}</pre>
</div>

<div class="ex" id="ExSortDate">
<p><a href="#ExSortDate">#4</a>: 获取根据修改日期排序的文件名:</p>
<pre>FileList := &quot;&quot;
遍历文件, 内_我的文档 "\Photos\*.*", "FD"  <em>; 包含文件和子目录</em>
    FileList .= 内_遍历文件修改时间 &quot;`t&quot; 内_遍历文件名 &quot;`n&quot;
FileList := 排序(FileList)  <em>; 根据日期排序.</em>
循环转换, FileList, "`n"
{
    如果 内_循环属性 = &quot;&quot; <em>; 忽略列表末尾的最后一个换行符(空项).</em>
        跳过
    FileItem := 分割字符串(内_循环属性, 内_跳格)  <em>; 用 tab 作为分隔符将其分为两部分.</em>
    Result := 信息框("The next file (modified at " FileItem[1] ") is:`n" FileItem[2] "`n`nContinue?",, "y/n")
    如果 Result = "No"
        跳出
}</pre>
</div>

<div class="ex" id="ExFileCopy">
<p><a href="#ExFileCopy">#5</a>: 仅复制比目标位置中的对应文件更新的源文件:</p>
<pre>CopyIfNewer:
<em>; 调用者已经为我们赋值了变量 CopySourcePattern 和 CopyDest.</em>
遍历文件, CopySourcePattern
{
    copy_it := false
    如果 !文件是否存在(CopyDest &quot;\&quot; 内_遍历文件名)  <em>; 如果目标文件还不存在, 那么总是复制.</em>
        copy_it := true
    否则
    {
        time := 获取文件时间(CopyDest "\" 内_遍历文件名)
        time := 取时间差(内_时间, 内_遍历文件修改时间, &quot;Seconds&quot;)  <em>; 从目的时间中减去源文件的时间.</em>
        如果 time &lt; 0  <em>; 源文件比目的文件新.</em>
            copy_it := true
    }
    如果 copy_it
    {
        try
            文件复制 内_遍历文件路径, CopyDest "\" 内_遍历文件名, 1   <em>; 以覆盖形式复制 overwrite=yes</em>
        捕获
            信息框 'Could not copy "' 内_遍历文件路径 '" to "' CopyDest '\' 内_遍历文件名 '".'
    }
}
返回</pre>
</div>

<div class="ex" id="ExLongPath">
<p><a href="#ExLongPath">#6</a>: 把通过命令行参数传递的文件名转换为长名称, 完整路径和在文件系统中存储的正确的大写/小写字符形式.</p>
<pre>遍历 GivenPath in A_Args  <em>; 对于每一个参数(或拖放到脚本中的文件):</em>
{
    遍历文件, GivenPath, "FD"  <em>; 包括文件和目录.</em>
        LongPath := 内_遍历文件路径
    信息框 "The 为-corrected long path name of file`n" GivenPath "`nis:`n" LongPath
}</pre>
</div>

</body>
</html>